package com.liwq.base.juc;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @author : liwq
 * @version : 1.0
 * @date : 2022/7/20
 * cyclicbarrier
 * 说明： 让一组线程到达某个屏障，然后被阻塞，一直到最后一个线程到达屏障，然后屏障开放，所有被阻塞的线程继续执行，计数器与线程数相等。
 * CyclicBarrier(int parties, Runnable barrierAction) 当时使用这个构造函数时，barrierAction定义的任务会执行
 * <p>
 * 举例说明： 假设有一家公司要全体员工进行团建活动，活动内容为翻越三个障碍物，
 * 每一个人翻越障碍物所用的时间是不一样的。但是公司要求所有人在翻越当前障碍物之后再开始翻越下一个障碍物，
 * 也就是所有人翻越第一个障碍物之后，才开始翻越第二个，以此类推比如跨栏比赛，我们修改一下规则，当所有选手都跨过第一个栏杆是，
 * 才去跨第二个，以此类推，每一个员工都是一个“其他线程”。当所有人都翻越的所有的障碍物之后，程序才结束。而主线程可能早就结束了，
 * 这里我们不用管主线程。
 **/
public class CyclicBarrierTest {

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    public static class Surmount implements Runnable {
        @Override
        public void run() {

            try {
                for (int i = 1; i < 4; i++) {
                    Random rand = new Random();
                    int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数
                    Thread.sleep(randomNum);
                    String name = Thread.currentThread().getName();
                    System.out.println(name + "翻过了第" + i + "个障碍");
                    cyclicBarrier.await();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 1; i < 6; i++) {
            Thread thread = new Thread(new Surmount(), "选手" + i);
            thread.start();
        }
        System.out.println("main is end");
    }
}
